package com.chujian.framework.ws.support.cli;

import com.chujian.framework.util.JsonUs;
import com.chujian.framework.ws.WsMsg;
import com.chujian.framework.ws.IWsRcver;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.scheduling.annotation.Scheduled;

import java.net.URI;

@Slf4j
public class WsCli extends WebSocketClient {

    private final IWsRcver wsRcver;

    public WsCli(URI serverUri, IWsRcver wsRcver) {
        super(serverUri, new Draft_6455());
        this.wsRcver = wsRcver;
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        log.info("onOpen： 建立连接");
    }

    @Override
    public void onMessage(String message) {
        log.debug("WsCli onMessage：{}", message);
        WsMsg msg = JsonUs.toObj(message, WsMsg.class);
        // 处理接收到的消息
        wsRcver.onRcv(msg, message);
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        log.warn("onClose： " + reason);
    }

    @Override
    public void onError(Exception ex) {
        log.error("ws通讯异常", ex);
    }

    /**
     * 自动重连
     */
    @Scheduled(fixedDelay = 2 * 1000)
    public void autoReConn() {
        doReConn();
    }

    /**
     * 发送 ping frame
     */
    @Scheduled(fixedDelay = 20 * 1000)
    public void autoPing() {
        this.sendPing();
    }

    /**
     * 执行重连
     */
    private void doReConn() {
        if (isNeedReConn()) {
            try {
                log.warn("ws自动重连");
                this.reconnect();
            } catch (Exception e) {
                log.error("ws重连失败", e);
            }
        }
    }

    /**
     * 是否需要重连
     *
     * @return
     */
    public boolean isNeedReConn() {
        return !this.isOpen() && (this.getReadyState() == ReadyState.CLOSED || this.getReadyState() == ReadyState.CLOSING);
    }


}
